<?php
/**
 * Responsável pela renderização das informações em forma de html para exibição em tela
 * @author cristiano
 *
 */
class SofiaUi extends Smarty {
	private static $instancia;
	private $pagina;

	/**
	 * @return Controle
	 */
	private $controle;

	/**
	 * @return SofiaUi
	 */
	public static function GetInstancia(){
        if(!SofiaUi::$instancia instanceof SofiaUi){
            SofiaUi::$instancia = new SofiaUi;
        }
        return SofiaUi::$instancia;
    }

    /**
     * Carrega o arquivo html do view para a memória, executas as funções de renderização
     * e exibe os dados em tela
     * @param $controle
     */
    public function Renderizar(Controle $controle){
    	if(Sistema::GetInstancia()->GetMedidor()) Velocimetro::GetInstancia()->Start("SofiaUi::Renderizar");
 
    	$this->Registracontrolador($controle)->Ajustar()->InsereComponentes();
    	$this->Ajustar();
    	$sistema = Sistema::GetInstancia();

    	$this->DefaultRender();
		$this->CarregaHtml($sistema->GetPaginaAtual()->GetArquivo());

		if($this->controle->NomeModelo()){
			if($this->controle->Persistencia()){
				$this->ConfiguraTelaPorModelo($this->controle); // Tem que configurar pra funcionar com Smarty
			}
		}

		$this->ConfiguraMensagem();
		if(Sistema::GetInstancia()->GetMedidor()) Velocimetro::GetInstancia()->End("SofiaUi::Renderizar");
		$this->display();
    }

    private function ExibeRelatorioVelocimetro(){
    	$html = Velocimetro::GetInstancia()->GetRelatorio();
    	$funcao = "<script type='text/javascript'>
							Sofia.Alert('Relatório de Performance','{$html}');
					   </script>";
    	$this->assign("relatorio", $funcao);
    }

    /**
     * Método construtor da classe
     */
	public function SofiaUi(){
		//include DIR_FRAMEWORK_INCLUDES . 'simple_html_dom.php';

		$this->template_dir = DS . "shell" . DS . "html" . DS;
	    $this->compile_dir  = DIR_SMARTY_OUTPUT;
	    $this->config_dir   = DIR_SMARTY_CONFIG;
	    $this->cache_dir    = DIR_SMARTY_OUTPUT;

	    $this->caching = false;
	}

	/**
	 * registra o controlador na classe
	 * @param Controle $ctrl
	 * @return SofiaUi
	 */
	public function RegistraControlador(Controle $ctrl){
		$this->controle = $ctrl;
		return $this;
	}

	/**
	 * Ajusta as tags registradas no controlador em variáveis para o smarty
	 * @return SofiaUi
	 */
	public function Ajustar(){
		if(Sistema::GetInstancia()->GetMedidor()) Velocimetro::GetInstancia()->Start("SofiaUi::Ajustar");
		
		$tmp_array = $this->controle->GetTrocaConteudo();
		foreach($tmp_array as $tag => $valor){
			$this->assign($tag, $valor);
		}
		
		if(Sistema::GetInstancia()->GetMedidor()) Velocimetro::GetInstancia()->End("SofiaUi::Ajustar");
		return $this;
	}

	/**
	 * função principal do view, carrega as master pages caso existam troca as tags do htmls por seus valores finais
	 * envia os dados para o smarty
	 * 
	 * @return void
	 */
	public function display(){
		if(Sistema::GetInstancia()->GetMedidor()) Velocimetro::GetInstancia()->Start("SofiaUi::display");

		if($this->controle->GetMaster()){
			$master = $this->controle->master;

			if(is_array($master)){ // dar looping no master por o master 0 dentro do master 1 dentro do master 2 e por ai vai...
				$last_master = end($master);
				array_pop($master);
				$tmp_conteudo = $this->GetVariavelRegistrada("conteudo");

				for($i = 0; $i < sizeof($master); $i++){
					$file = DIR_MASTER . strtolower($master[$i]) . '.html';
					//$tmp_master_conteudo = file_get_contents($file);
					$tmp_master_conteudo = $this->fetch($file);

					//$pag = str_replace('{$conteudo}', $tmp_conteudo, $tmp_master_conteudo);
					$this->clear_assign("conteudo");
					$this->assign("conteudo", $tmp_master_conteudo);
				}

				$file = "masters/" . $last_master . ".html";
			}else{
				$file = "masters/" .$master . ".html";
			}

			if(Sistema::GetInstancia()->GetMedidor()) Velocimetro::GetInstancia()->End("SofiaUi::display");

			if(Sistema::GetInstancia()->GetMedidor()) $this->ExibeRelatorioVelocimetro();
			parent::display($file);
		}else{
			if(Sistema::GetInstancia()->GetMedidor()) Velocimetro::GetInstancia()->End("SofiaUi::display");

			if(Sistema::GetInstancia()->GetMedidor()) $this->ExibeRelatorioVelocimetro();
			parent::display(Sistema::GetInstancia()->GetPaginaAtual()->GetArquivo());
		}
	}

	/**
	 * carrega o arquivo html vinculado ao controlador
	 * @param unknown_type $nome
	 */
 	public function CarregaHtml($nome){
 		if(Sistema::GetInstancia()->GetMedidor()) Velocimetro::GetInstancia()->Start("SofiaUi::CarregaHtml");

 		if($this->controle->master){
 			$arquivo = Sistema::GetInstancia()->GetPaginaAtual()->GetArquivo();
 			$content = $this->fetch($arquivo);
 			$this->assign('conteudo', $content);
 		}

 		if(Sistema::GetInstancia()->GetMedidor()) Velocimetro::GetInstancia()->End("SofiaUi::CarregaHtml");
    }

    /**
     * renderiza tags padrão como nome, ir, usuarios e registra o datagrid no smarty
     */
	public function DefaultRender(){
		if(Sistema::GetInstancia()->GetMedidor()) Velocimetro::GetInstancia()->Start("SofiaUi::DefaultRender");

        $ses = Sessao::GetInstanciar();
        $usuario = array("nome" => $ses->GetVarSessao("usuario"),
        				 "id"	=> $ses->GetVarSessao('userid'));

        $this->assign("usuario", $usuario);
		$this->assign("sistema", APP_FOLDER);
		
        //Datagrid
        if($this->controle->GridCampos()){
        	$datagrid = $this->controle->GeraDataGrid(true);
        	$this->assign("datagrid", $datagrid);
        }

        if(Sistema::GetInstancia()->GetMedidor()) Velocimetro::GetInstancia()->End("SofiaUi::DefaultRender");
    }

    /**
     * insere componentes externos no html tais como js, css
     * @return SofiaUi
     */
	public function InsereComponentes(){
		if(Sistema::GetInstancia()->GetMedidor()) Velocimetro::GetInstancia()->Start("SofiaUi::InsereComponentes");

        $controle = $this->controle->GetSistema()->GetPaginaAtual()->GetNome();
        $javascript = $this->controle->GetSistema()->GetPaginaAtual()->GetJavascript();
        $css_file = SITE_ROOT . "shell\\css\\" . $controle . ".css";
      //  die($css_file);
        if(file_exists($css_file)){
        	$tmp_css = APP_FOLDER . "/shell/css/" . $controle . '.css';
        	$css = "<link rel='stylesheet' type='text/css' href='$tmp_css' />";	
        }else{
        	$css = "";
        }

        if($javascript != ""){
        	$tmp_js = APP_FOLDER . "/shell/js/" . $javascript;
        	$js = "<script type='text/javascript' src='$tmp_js'></script>";
        }else{
        	$js = "";
        }

        $this->assign("js", $js);
        $this->assign("css", $css);

        if(Sistema::GetInstancia()->GetMedidor()) Velocimetro::GetInstancia()->End("SofiaUi::InsereComponentes");
        
        return $this;
    }

    /**
     * configura os campos dos formularios com base no modelo vinculado ao controlador
     * 
     * @param $control
     */
	public function ConfiguraTelaPorModelo(Controle $control){
		if(Sistema::GetInstancia()->GetMedidor()) Velocimetro::GetInstancia()->Start("SofiaUi::ConfiguraTelaPorModelo");
		
    	$mod = $control->Modelo();

    	$gets = get_class_methods($mod);
    	$dom = $this->StrParaHtml($this->pagina);

		$radio_fill = false;

        for($i = 0; $i < sizeof($gets); $i++){
            if(strpos($gets[$i], 'get_') == 0){

                $input = $dom->getElementById( str_replace('get_', '', $gets[$i]) );
                if($input){
                	$metodo = $gets[$i];

					//Tratando os inputs type: text, password, hidden
					$attr_type = $input->getAttribute('type');
					if($attr_type == 'text' || $attr_type == 'password' || $attr_type == 'hidden'){
						$input->setAttribute('value', $mod->$metodo());
					}

					//Tratando os inputs type: radio
					if($attr_type == 'radio'){
						if(!$radio_fill){
							$radios = $input->getElementsByTagName('radio');
							foreach($radios as $radio){
								if($radio->getAttribute('value') == $mod->metodo()){
									$radio->setAttribute('checked', 'checked');
								}
							}
							$radio_fill = true;
						}
					}

					//Tratando os inputs type: checkbox
					if($attr_type == 'checkbox'){
						$nome_metodo = str_replace('get_', '', $metodo);
						$selector = 'input[name="' . $nome_metodo . '"]';
						$checkboxes = $dom->find($selector);

						foreach($checkboxes as $checkbox){
	            	   		if($checkbox->getAttribute('name') == $nome_metodo){
	            	   			if($mod->$metodo()){
	            	   				$checkbox->setAttribute('checked', 'checked');
	            	   			}
	            	   		}
	                	}
					}

					//Tratando os textareas
                	if($input->hasAttribute('rows')){ 
                	   $nome_metodo = str_replace('get_', '', $metodo);
                	   $selector = 'textarea[name="' . $nome_metodo . '"]';
                	   $textareas = $dom->find($selector);

                	   if($textareas instanceof simple_html_dom_node){
                	   		if($textareas->getAttribute('name') == $nome_metodo)
                	   			$textareas->innertext = $mod->$metodo();
                	   }else{
	                	   foreach($textareas as $textarea){
	                	   		if($textarea->getAttribute('name') == $nome_metodo){
	                	   			$textarea->innertext = $mod->$metodo();
	                	   		}
	                	   }
                	   }
                	}

                	//Tratando os selects
                	if($input->hasAttribute('title') && $input->getAttribute('title') == 'select'){ 
                	   
                	}

                }
            }
        }

        $this->pagina = $dom->save();
        
        if(Sistema::GetInstancia()->GetMedidor()) Velocimetro::GetInstancia()->End("SofiaUi::ConfiguraTelaPorModelo");
    }

    /**
     * configura mensagem para ser exibida no onload da pagina quando há alguma
     */
	public function ConfiguraMensagem(){
		if(Sistema::GetInstancia()->GetMedidor()) Velocimetro::GetInstancia()->Start("SofiaUi::ConfiguraMensagem");

    	if(sizeof(Mensagens::GetMensagem()) > 0){
    		$msn = Mensagens::GetMensagem();
    		$funcao = "<script type='text/javascript'>
							Sofia.Alert(\"{$msn['titulo']}\",\"{$msn['conteudo']}\");
					   </script>";
    		$this->assign("mensagem", $funcao);
    	}

    	if(Sistema::GetInstancia()->GetMedidor()) Velocimetro::GetInstancia()->End("SofiaUi::ConfiguraMensagem");
    }

    /**
     * parser string em html
     * 
     * @param string
     * @return SimpleDomNode
     */
	public function StrParaHtml($string){
		if(Sistema::GetInstancia()->GetMedidor()) Velocimetro::GetInstancia()->Start("SofiaUi::StrParaHtml");
		
		$parser = new SimpleDomParser($string);
		$dom = new SimpleDomNode($parser);
		
		if(Sistema::GetInstancia()->GetMedidor()) Velocimetro::GetInstancia()->End("SofiaUi::StrParaHtml");
    	return $dom;
    }

    /**
     * muda valor de algum elemento html possuidor de atributo value
     * @param $valores
     */
	public function MudaValor(array $valores){
		if(Sistema::GetInstancia()->GetMedidor()) Velocimetro::GetInstancia()->Start("SofiaUi::MudaValor");
		
    	$dom = $this->StrParaHtml($this->pagina);
		foreach($valores as $id => $valor){
			$elemento = $dom->getElementById($id);
			$elemento->setAttribute('value', $valor);
		}
    	$this->pagina = $dom->save();
    	
    	if(Sistema::GetInstancia()->GetMedidor()) Velocimetro::GetInstancia()->End("SofiaUi::MudaValor");
    }

    /**
     * Retorna variavel registrada pelo smarty
     * @param string
     */
    public function GetVariavelRegistrada($var){
    	return $this->_tpl_vars[$var];
    }
}